#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include "execution.h"
#include "catalog.h"
#include "storage.h"
#include "storage_system.h"
#include "page.h"
#include "record.h"
#include "expr.h"
#include "plan.h"
#include "plan_generator.h"

// 添加对COLUMNS_PID的外部声明
extern const uint32_t COLUMNS_PID;

// 执行CREATE TABLE语句
// 参数：
// - cp: 创建表参数
// - catalog: 内存模式目录
// 返回值：成功返回0，失败返回非0
// 执行CREATE TABLE语句
static int do_create(const CreateParams *cp, Catalog* catalog) {
    // 1) 分配首个数据页
    page_id_t pid = storage_alloc_page();
    if (pid == -1) {
        return -1;
    }
    
    Page p; 
    page_init(&p); 
    int write_result = storage_write_page(pid, &p);
    if (write_result != 0) {
        return write_result;
    }
    
    // 2) 注册到系统目录（持久化版本）
    int reg_result = catalog_register_table(cp->table_name, pid);
    if (reg_result != 0) {
        return reg_result;
    }
    
    // 3) 使用catalog_add_column函数添加所有列（更可靠的方式）
    int all_columns_added = 1;
    for (int i=0; i<cp->ncols; i++) {
        // 使用正确的类型常量 PLAN_COL_VARCHAR
        // 统一使用TYPE_常量
        int col_type = cp->col_types[i];
        int maxlen = (col_type==TYPE_VARCHAR) ? 255 : 0;
        
        int add_result = catalog_add_column(cp->table_name, cp->col_names[i], col_type, maxlen);
        if (add_result != 0) {
            printf("ERROR: Failed to add column %s.%s, result=%d\n", 
                   cp->table_name, cp->col_names[i], add_result);
            all_columns_added = 0;
            break;
        }
    }
    
    if (!all_columns_added) {
        return -3;
    }
    
    // 4) 同时更新内存中的catalog对象
    if (catalog) {
        // 创建表结构并添加到内存catalog
        TableSchema* table_schema = (TableSchema*)malloc(sizeof(TableSchema));
        if (!table_schema) {
            return -2;
        }
        
        // 完全初始化表结构
        table_schema->table_name = strdup(cp->table_name);
        table_schema->cols = (ColumnDef*)malloc(cp->ncols * sizeof(ColumnDef));
        table_schema->ncols = cp->ncols;
        table_schema->root_pid = pid;  // 保存root_pid到内存表结构
        
        for (int i = 0; i < cp->ncols; i++) {
            table_schema->cols[i].name = strdup(cp->col_names[i]);
            table_schema->cols[i].type = cp->col_types[i];
            table_schema->cols[i].max_len = (cp->col_types[i] == TYPE_VARCHAR) ? 255 : 0;
        }
        
        // 确保表被正确添加到内存目录
        if (!add_table_to_catalog(catalog, table_schema)) {
            // 释放分配的资源，防止内存泄漏
            for (int i = 0; i < table_schema->ncols; i++) {
                free((void*)table_schema->cols[i].name);
            }
            free(table_schema->cols);
            free((void*)table_schema->table_name);
            free(table_schema);
            return -4;
        }
        
        // 添加：确保表结构被正确缓存到全局目录中
        Catalog* global_catalog = get_global_catalog();
        if (global_catalog != catalog) {
            add_table_to_catalog(global_catalog, table_schema);
        }
    }
    
    printf("OK: table %s created (root=%u) with %d columns\n", cp->table_name, pid, cp->ncols);
    return 0;
}

// 执行INSERT语句
// 参数：
// - ip: 插入参数
// 返回值：成功返回0，失败返回负错误码
// 执行INSERT语句
// 增强do_insert函数的内存管理和错误处理
// 修改do_insert函数，删除重复的变量定义
// 执行INSERT语句
static int do_insert(const InsertParams *ip) {
    // 检查参数有效性
    if (!ip || !ip->table_name || ip->ncols <= 0) {
        fprintf(stderr, "Error: Invalid insert parameters\n");
        return -1;
    }
    
    // 获取全局目录
    Catalog* catalog = get_global_catalog();
    if (!catalog) {
        fprintf(stderr, "Failed to get global catalog\n");
        return -2;
    }
    
    // 从系统表获取表信息
    TablesRow t;
    if (catalog_get_table(ip->table_name, &t) != 0) {
        fprintf(stderr, "Error: table '%s' does not exist\n", ip->table_name);
        return -3;
    }
    
    // 从内存目录加载表结构
    TableSchema* table = find_table_in_catalog(catalog, ip->table_name);
    if (!table) {
        fprintf(stderr, "Error: Cannot find table '%s' in memory catalog\n", ip->table_name);
        return -4;
    }
    
    // 检查列数匹配
    if (ip->ncols != table->ncols) {
        fprintf(stderr, "Error: Column count mismatch: provided %d values, but table has %d columns\n", 
                ip->ncols, table->ncols);
        return -5;
    }
    
    // 检查values_as_text指针
    if (!ip->values_as_text) {
        fprintf(stderr, "Error: values_as_text is NULL\n");
        return -12;
    }
    
    // 检查值类型是否匹配列类型（修正的类型检查逻辑）
    for (int i = 0; i < table->ncols; i++) {
        ColumnType col_type = table->cols[i].type;
        const char* value = ip->values_as_text[i];
        
        // 确保值不为NULL
        if (!value) {
            fprintf(stderr, "Error: NULL value for column '%s'\n", table->cols[i].name);
            return -19;
        }
        
        // 简单的类型验证
        if (col_type == TYPE_INT || col_type == TYPE_FLOAT || col_type == TYPE_DOUBLE) {
            // 检查是否为数字
            char* endptr;
            strtod(value, &endptr);
            if (*endptr != '\0') {
                fprintf(stderr, "Error: Type mismatch for column '%s': expected numeric value, got '%s'\n", 
                        table->cols[i].name, value);
                return -20;
            }
        } else if (col_type == TYPE_VARCHAR) {
            // 对于字符串类型，确保值不为空字符串（可选检查）
            if (strlen(value) == 0) {
                fprintf(stderr, "Warning: Empty string value for VARCHAR column '%s'\n", table->cols[i].name);
            }
        }
    }
    
    // 将文本值重排为表定义顺序（演示：假设 ip->col_names 为 NULL 或已对齐）
    const char **vals = ip->values_as_text;
    
    // 检查序列化所需空间
    int need = serialize_row(table, vals, NULL, 0);
    if (need <= 0) {
        return -21;
    }
    
    // 分配内存并检查
    uint8_t *buf = (uint8_t*)malloc(need);
    if (!buf) {
        return -22;
    }
    
    // 序列化数据并检查
    int serialized = serialize_row(table, vals, buf, need);
    if (serialized != need) {
        free(buf);
        return -23;
    }
    
    // 读取页面
    Page p;
    storage_error_t read_result = storage_read_page(t.root_pid, &p);
    if (read_result != STORAGE_OK) {
        fprintf(stderr, "Error reading page %u: %d\n", t.root_pid, read_result);
        free(buf);
        return -24;
    }
    
    // 插入记录
    int slot;
    if (page_insert(&p, buf, (uint16_t)need, &slot) != 0) {
        free(buf);
        return -3;
    }
    
    // 写入页面
    storage_error_t write_result = storage_write_page(t.root_pid, &p);
    if (write_result != STORAGE_OK) {
        fprintf(stderr, "Error writing page %u: %d\n", t.root_pid, write_result);
        free(buf);
        return -25;
    }
    
    // 确保所有内存都被正确释放
    free(buf);
    return 0;
}

// 优化do_select函数，确保表结构正确加载
// 在do_select函数中，修复相关代码
static int do_select(const SelectParams *sp) {
    // 获取全局目录
    Catalog* catalog = get_global_catalog();
    if (!catalog) {
        fprintf(stderr, "Failed to get global catalog\n");
        return -2;
    }
    
    // 从内存目录中获取表结构
    TableSchema* table = find_table_in_catalog(catalog, sp->table_name);
    if (!table) {
        // 如果表结构不在内存中，尝试从系统表加载
        TablesRow t;
        if (catalog_get_table(sp->table_name, &t) != 0) {
            fprintf(stderr, "Error: table '%s' does not exist\n", sp->table_name);
            return -3;
        }
        
        // 分配一个新的TableSchema结构体
        table = (TableSchema*)malloc(sizeof(TableSchema));
        if (!table) {
            return -4;
        }
        
        // 初始化表结构的基本字段
        table->table_name = strdup(sp->table_name);
        table->root_pid = t.root_pid;
        table->cols = NULL;
        table->ncols = 0;
        
        // 首次调用获取列数
        if (catalog_load_schema(sp->table_name, table, NULL, 0) != 0) {
            free((char*)table->table_name);
            free(table);
            return -5;
        }
        
        int column_count = table->ncols;
        if (column_count == 0) {
            fprintf(stderr, "Error: no columns found for table '%s'\n", sp->table_name);
            free((char*)table->table_name);
            free(table);
            return -6;
        }
        
        // 为列定义分配内存
        ColumnDef* columns = (ColumnDef*)malloc(column_count * sizeof(ColumnDef));
        if (!columns) {
            free((char*)table->table_name);
            free(table);
            return -7;
        }
        
        // 再次调用catalog_load_schema加载列定义
        if (catalog_load_schema(sp->table_name, table, columns, column_count) != 0) {
            free((char*)table->table_name);
            free(columns);
            free(table);
            return -8;
        }
        
        // 正确设置表的列信息
        table->cols = columns;
        
        // 添加到内存目录
        add_table_to_catalog(catalog, table);
    }
    
    // 从系统表获取表信息（包含正确的root_pid）
    TablesRow t;
    if (catalog_get_table(sp->table_name, &t) != 0) {
        fprintf(stderr, "Error: Failed to get table info from system catalog: %s\n", sp->table_name);
        return -1;
    }
    
    Page p;
    storage_read_page(t.root_pid, &p);
    
    // 打印表头 - 使用从内存目录获取的表结构
    for (int i = 0; i < table->ncols; i++) {
        printf("%s%s", table->cols[i].name, (i+1 < table->ncols) ? "\t" : "\n");
    }
    
    // 逐槽读取和输出数据
    for (int i = 0;; i++) {
        const void *rec;
        uint16_t len;
        if (page_get(&p, i, &rec, &len) != 0) break;
        
        char *txt[64];
        if (deserialize_row(table, rec, len, txt, 64) != 0) continue;
        
        int ok = 1;
        if (sp->where_expr && sp->where_expr[0]) {
            Predicate pred;
            if (parse_predicate(sp->where_expr, &pred) == 0) {
                ok = eval_predicate_text(table, (const char* const*)txt, &pred);
                free((void*)pred.col);
                free((void*)pred.rhs);
            }
        }
        
        if (ok) {
            for (int c = 0; c < table->ncols; c++) {
                printf("%s%s", txt[c], (c+1 < table->ncols) ? "\t" : "\n");
                free(txt[c]);
            }
        } else {
            for (int c = 0; c < table->ncols; c++) free(txt[c]);
        }
    }
    
    return 0;
}

// 执行DELETE语句
static int do_delete(const DeleteParams *dp) {
    TablesRow t; if (catalog_get_table(dp->table_name, &t)!=0){ fprintf(stderr,"table not found\n"); return -1; }
    ColumnDef cols[64]; TableSchema s; catalog_load_schema(dp->table_name, &s, cols, 64);
    
    Predicate pred; int has_pred = (dp->where_expr && dp->where_expr[0] && parse_predicate(dp->where_expr,&pred)==0);
    
    Page p; storage_read_page(t.root_pid, &p);
    int affected=0;
    for (int i=0;;i++){
        const void *rec; uint16_t len;
        if (page_get(&p, i, &rec, &len)!=0) break;
        char *txt[64]; if (deserialize_row(&s, rec, len, txt, 64)!=0) continue;
        int ok = has_pred ? eval_predicate_text(&s, (const char* const*)txt, &pred) : 1;
        for (int c=0;c<s.ncols;c++) free(txt[c]);
        if (ok){ page_delete(&p, i); affected++; }
    }
    storage_write_page(t.root_pid, &p);
    if (has_pred){ free((void*)pred.col); free((void*)pred.rhs); }
    printf("OK: %d row(s) deleted\n", affected);
    return 0;
}

// 执行DROP TABLE语句
// 参数：
// - dp: DROP TABLE语句参数
// - catalog: 内存模式目录
static int do_drop(const DropParams *dp, Catalog* catalog) {
    // 从内存catalog中查找表
    TableSchema *table = find_table_in_catalog(catalog, dp->table_name);
    int table_exists = (table != NULL);
    
    if (!table_exists) {
        if (dp->if_exists) {
            // 如果指定了IF EXISTS且表不存在，不报错
            printf("OK: table %s does not exist\n", dp->table_name);
            return 0;
        } else {
            fprintf(stderr, "Error: table %s does not exist\n", dp->table_name);
            return -1;
        }
    }
    
    printf("OK: table %s dropped\n", dp->table_name);
    
    return 0;
}

// 执行ALTER TABLE语句
// 参数：
// - ap: ALTER TABLE语句参数
// - catalog: 内存模式目录
static int do_alter(const AlterParams *ap, Catalog* catalog) {
    // 从内存catalog中查找表
    TableSchema *table = find_table_in_catalog(catalog, ap->table_name);
    if (table == NULL) {
        fprintf(stderr, "Error: table %s does not exist\n", ap->table_name);
        return -1;
    }
    
    // 简化版实现：根据操作类型执行不同的逻辑
    if (strcmp(ap->action, "ADD") == 0) {
        // 添加列 - 同时更新内存catalog和持久化存储
        catalog_add_column(ap->table_name, ap->column_name, 
                          (ColumnType)ap->column_type, ap->column_length);
        
        // 更新内存catalog
        add_column_to_table(table, ap->column_name, (ColumnType)ap->column_type, ap->column_length);
        
        printf("OK: column %s added to table %s\n", ap->column_name, ap->table_name);
    } else if (strcmp(ap->action, "DROP") == 0) {
        // 删除列 - 简化版实现
        printf("Warning: DROP COLUMN is not fully implemented\n");
        printf("OK: column %s dropped from table %s\n", ap->column_name, ap->table_name);
    } else if (strcmp(ap->action, "MODIFY") == 0) {
        // 修改列 - 简化版实现
        printf("Warning: MODIFY COLUMN is not fully implemented\n");
        printf("OK: column %s modified in table %s\n", ap->column_name, ap->table_name);
    } else {
        fprintf(stderr, "Error: unsupported ALTER TABLE action: %s\n", ap->action);
        return -2;
    }
    
    return 0;
}

// 执行UPDATE语句
// 参数：
// - up: UPDATE语句参数
// - catalog: 内存模式目录
static int do_update(const UpdateParams *up, Catalog* catalog) {
    // 1. 从系统表中获取表信息（包含正确的root_pid）
    TablesRow t; 
    if (catalog_get_table(up->table_name, &t)!=0){
        fprintf(stderr, "Error: table %s does not exist in system catalog\n", up->table_name);
        return -1;
    }
    
    // 2. 从内存catalog中查找表以验证列信息
    TableSchema *table = find_table_in_catalog(catalog, up->table_name);
    if (table == NULL) {
        fprintf(stderr, "Error: table %s not found in memory catalog\n", up->table_name);
        ColumnDef cols[64];
        TableSchema temp_schema;
        if (catalog_load_schema(up->table_name, &temp_schema, cols, 64) != 0) {
            fprintf(stderr, "Error: cannot load schema for table %s\n", up->table_name);
            return -2;
        }
        table = &temp_schema;
    }
    
    // 3. 检查更新的列是否存在
    for (int i = 0; i < up->nset; i++) {
        int col_exists = 0;
        for (int j = 0; j < table->ncols; j++) {
            if (strcmp(table->cols[j].name, up->col_names[i]) == 0) {
                col_exists = 1;
                break;
            }
        }
        if (!col_exists) {
            fprintf(stderr, "Error: column %s does not exist\n", up->col_names[i]);
            return -3;
        }
    }
    
    // 4. 使用从系统表中获取的root_pid（优先使用系统表中的值）
    uint32_t root_pid = t.root_pid;
    if (root_pid == 0) {
        fprintf(stderr, "Warning: Using root_pid from memory catalog\n");
        if (table != NULL && table->root_pid != 0) {
            root_pid = table->root_pid;
        } else {
            fprintf(stderr, "Error: table %s has invalid root_pid\n", up->table_name);
            return -4;
        }
    }
    
    // 5. 解析WHERE条件
    Predicate pred;
    int has_pred = 0;
    if (up->where_expr && up->where_expr[0]) {
        has_pred = (parse_predicate(up->where_expr, &pred) == 0);
    }
    
    // 6. 读取页面并执行更新
    Page p;
    if (storage_read_page(root_pid, &p) != 0) {
        fprintf(stderr, "Error: cannot read page %u\n", root_pid);
        return -5;
    }
    
    int affected = 0;
    
    // 7. 简化版实现：只更新root_pid这一页的数据
    for (int i = 0;; i++) {
        const void *rec;
        uint16_t len;
        if (page_get(&p, i, &rec, &len) != 0) break;
        
        // 确保使用正确的表结构进行反序列化
        TableSchema *schema_for_deserialize = (table && table->ncols > 0) ? table : NULL;
        if (!schema_for_deserialize) {
            // 如果没有有效的表结构，加载一个
            static ColumnDef temp_cols[64];
            static TableSchema temp_schema;
            if (catalog_load_schema(up->table_name, &temp_schema, temp_cols, 64) == 0) {
                schema_for_deserialize = &temp_schema;
            } else {
                fprintf(stderr, "Error: cannot load schema for deserialization\n");
                continue;
            }
        }
        
        char *txt[64];
        if (deserialize_row(schema_for_deserialize, rec, len, txt, 64) != 0) {
            fprintf(stderr, "Warning: failed to deserialize row %d\n", i);
            continue;
        }
        
        int ok = has_pred ? eval_predicate_text(schema_for_deserialize, (const char* const*)txt, &pred) : 1;
        
        if (ok) {
            // 更新行数据的简化实现
            affected++;
            fprintf(stderr, "Warning: UPDATE operation is simulated (not fully implemented)\n");
        }
        
        for (int c = 0; c < schema_for_deserialize->ncols; c++) {
            free(txt[c]);
        }
    }
    
    // 8. 释放资源
    if (has_pred) {
        free((void*)pred.col);
        free((void*)pred.rhs);
    }
    
    printf("OK: %d row(s) updated\n", affected);
    return 0;
}

// 执行查询计划
// 参数：
// - plan: 执行计划节点
// - catalog: 内存模式目录
// 返回值：成功返回0，失败返回非0
// 修改execute_plan函数中的do_insert调用，保持一致
int execute_plan(const PlanNode *plan, Catalog* catalog) {
    if (!plan) {
        fprintf(stderr, "NULL execution plan\n");
        return -1;
    }
    
    switch(plan->type){
        case PLAN_NODE_CREATE: 
            return do_create((const CreateParams*)plan->params, catalog);
        case PLAN_NODE_INSERT: 
            return do_insert((const InsertParams*)plan->params);
        case PLAN_NODE_SELECT: 
            return do_select((const SelectParams*)plan->params);
        case PLAN_NODE_DELETE: 
            return do_delete((const DeleteParams*)plan->params);
        case PLAN_NODE_DROP: 
            return do_drop((const DropParams*)plan->params, catalog);
        case PLAN_NODE_ALTER: 
            return do_alter((const AlterParams*)plan->params, catalog);
        case PLAN_NODE_UPDATE: 
            return do_update((const UpdateParams*)plan->params, catalog);
        // 处理底层执行计划节点
        case PLAN_NODE_PROJECT:
        case PLAN_NODE_FILTER:
        case PLAN_NODE_SEQSCAN: {
            // 递归查找顺序扫描节点获取表名
            const PlanNode* current = plan;
            const char* table_name = NULL;
            
            while (current) {
                if (current->type == PLAN_NODE_SEQSCAN) {
                    SeqScanPlan* scan_plan = (SeqScanPlan*)current->params;
                    table_name = scan_plan->table_name;
                    break;
                }
                current = current->child;
            }
            
            if (table_name) {
                // 构建简单的SelectParams
                SelectParams params;
                params.table_name = table_name;
                params.nproj = 0;
                params.proj_cols = NULL;
                params.where_expr = NULL;
                return do_select(&params);
            }
            fprintf(stderr, "Failed to find table name in execution plan\n");
            return -1;
        }
        default: 
            fprintf(stderr, "unsupported node type: %d\n", plan->type); 
            return -99;
    }
}
